package com.aptemo.webetek.client.widgets;

import java.util.Date;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.HasChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.impl.TextBoxImpl;

public class TimeEditWidget
		extends FocusWidget implements HasValue<Date>, HasChangeHandlers
{
	private static TextBoxImpl	impl		= GWT.create(TextBoxImpl.class);

	private DateTimeFormat		formatter	= DateTimeFormat.getShortTimeFormat();
	private boolean				valueChangeHandlerInitialized;

	public TimeEditWidget()
	{
		super(Document.get().createTextInputElement());
		setStyleName("gwt-TextBox");
	}

	@Override
	public void setValue(Date value)
	{
		setValue(value, false);
	}

	@Override
	public void setValue(Date value, boolean fireEvents)
	{
		Date oldValue = getValue();
		setText(formatter.format(value));
		if (fireEvents)
		{
			ValueChangeEvent.fireIfNotEqual(this, oldValue, value);
		}
	}

	@Override
	public Date getValue()
	{
		String text = getText();
		if (text == null || text.isEmpty())
		{
			return null;
		}
		return formatter.parse(text);
	}

	@Override
	public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Date> handler)
	{
		// Initialization code
		if (!valueChangeHandlerInitialized)
		{
			valueChangeHandlerInitialized = true;
			addChangeHandler(new ChangeHandler()
			{
				public void onChange(ChangeEvent event)
				{
					ValueChangeEvent.fire(TimeEditWidget.this, getValue());
				}
			});
		}
		return addHandler(handler, ValueChangeEvent.getType());
	}

	public HandlerRegistration addChangeHandler(ChangeHandler handler)
	{
		return addDomHandler(handler, ChangeEvent.getType());
	}

	public String getName()
	{
		return DOM.getElementProperty(getElement(), "name");
	}

	/**
	 * Gets the text currently selected within this text box.
	 * 
	 * @return the selected text, or an empty string if none is selected
	 */
	public String getSelectedText()
	{
		int start = getCursorPos();
		if (start < 0)
		{
			return "";
		}
		int length = getSelectionLength();
		return getText().substring(start, start + length);
	}

	/**
	 * Gets the length of the current text selection.
	 * 
	 * @return the text selection length
	 */
	public int getSelectionLength()
	{
		return impl.getSelectionLength(getElement());
	}

	public String getText()
	{
		return DOM.getElementProperty(getElement(), "value");
	}

	/**
	 * Gets the current position of the cursor (this also serves as the
	 * beginning of the text selection).
	 * 
	 * @return the cursor's position
	 */
	public int getCursorPos()
	{
		return impl.getCursorPos(getElement());
	}

	/**
	 * Sets this object's text. Note that some browsers will manipulate the text
	 * before adding it to the widget. For example, most browsers will strip all
	 * <code>\r</code> from the text, except IE which will add a <code>\r</code>
	 * before each <code>\n</code>. Use {@link #getText()} to get the text
	 * directly from the widget.
	 * 
	 * @param text
	 *            the object's new text
	 */
	public void setText(String text)
	{
		DOM.setElementProperty(getElement(), "value", text != null ? text : "");
	}
}
